import './monaco-editor.scss';
import {designComponent, getComponentCls, onMounted, PropType, reactive, useClassCache, useModel, useRefs} from "@peryl/react-compose";
import {MonacoLoader} from "./monaco.utils";
import {ApplicationConfigurationProvider, LoadingMask} from "plain-design";

export const MonacoEditor = designComponent({
  props: {
    modelValue: { type: String },
    language: { type: String as PropType<'javascript' | 'css' | 'html' | 'json' | 'typescript'>, required: true },
    theme: { type: String as PropType<'vs' | 'vs-dark' | 'hc-black'> },
    fullHeight: { type: Boolean },
    readonly: { type: Boolean, default: false },
    // publicPath: { type: String, required: true },
  },
  emits: {
    onUpdateModelValue: (val: any) => true,
    onKeydown: (e: any) => true,
  },
  setup({ props, event: { emit } }) {

    const configuration = ApplicationConfigurationProvider.inject();

    let ins: any;

    const classes = useClassCache(() => [
      getComponentCls('monaco-editor'),
      { "monaco-editor-full-height": props.fullHeight, }
    ]);

    const model = useModel(() => props.modelValue, emit.onUpdateModelValue, {
      onChange: val => {
        !!ins && ins.setValue(val || '');
      }
    });
    const { refs, onRef } = useRefs({ el: HTMLDivElement });

    const state = reactive({
      ready: false,
    });

    onMounted(async () => {

      const monaco = await MonacoLoader.getMonaco(/*props.publicPath*/);

      state.ready = true;

      ins = monaco.editor.create(refs.el!, {
        value: model.value,
        language: props.language,
        theme: props.theme ?? configuration.value.theme.dark ? 'vs-dark' : 'cs',
        fontSize: '14px',
        fontFamily: 'unset',
        readOnly: props.readonly,
      });

      ins.onDidChangeModelContent(() => {
        model.value = ins.getValue();
      });

      ins.onKeyDown(emit.onKeydown);

      return () => {
        ins.dispose();
      };
    });

    return () => (
      <div className={classes.value}>
        <LoadingMask modelValue={!state.ready}/>
        <div ref={onRef.el} className="monaco-editor-ele"/>
      </div>
    );
  },
});
